package com.visp.midiproxy;

import java.io.IOException;
import java.net.ServerSocket;
import java.net.Socket;
import java.util.Enumeration;
import java.util.Vector;

/**
 * Originally from the FLOSC project at http://www.benchun.net/flosc/
 */

public class TcpServer extends Thread {
	private Vector clients = new Vector();  // all connected Flash clients
    private int port;                       // the TCP port
    ServerSocket server;                    // the TCP server
    
    /**
     * Constructor for the BasicTcpServer.
     * @param   port   TCP port for Flash client connections.
    */
    public TcpServer(int port) {
    	this.port = port;
        // System.out.println("TcpServer created on port: " + this.port);
    }


    /**
     * Thread run method.  Monitors incoming messages.
    */	
    @SuppressWarnings("unchecked")
	public void run() {
        try {
            // --- create a new TCP server
            server = new ServerSocket(port);
            // --- while the server is active...
            while(true) {
                // --- ...listen for new client connections
                Socket socket = server.accept();
                TcpClient client = new TcpClient(this, socket);
                // --- add the new client to our client list 
                clients.addElement(client);
                // --- start the client thread
                client.start();
            }
        } catch(IOException ioe) {
        	// System.out.println("Killing TCP server due to no connections..");
            // Debug.writeActivity("Server error...Stopping TCP XML/Flash server");
            // kill this server
            killServer();
        } 
    }

    /**
     * Broadcasts a message to all connected Flash clients.
     * Messages are terminated with a null character.
     *
     * @param   message    The message to broadcast.
    */
    public synchronized void broadcastMessage(String message) {
        // --- add the null character to the message
        message += '\0';
        
        // --- enumerate through the clients and send each the message
        Enumeration e = clients.elements();
        while (e.hasMoreElements()) {
            TcpClient client = (TcpClient)e.nextElement();
            client.send(message);
        }
    }

    /**
     * Replaces escape codes in a string with the literal
     * characters. (e.g.: "%20" is replaced with a space).
     *
     * (c) 2001 by Phil Scovis, all rights reserved.  This code is
     * provided as-is, without warranty.  You may copy, use, or
     * distribute this code, provided that you add value to it and
     * include this notice.
     *
     * @param s the string with escape codes.
     * @return the string with the escape codes replaced.
     */
    public String unescape(String s){
		String retval="";
		for (int i=0; i<s.length(); i++){
		    switch(s.charAt(i)){
		    case '%':
			String hexCode = s.substring(i+1, i+3);
			int hexValue = Integer.parseInt(hexCode,16);
			retval+=(char)hexValue;
			i+=2;
			break;
		    default:		
			retval+=s.charAt(i);
		    }
		}
		return retval;
    }
    
    


    /**
     * Removes clients from the client list.
     *
     * @param   client    The TcpClient to remove.
     *
    */
    public void removeClient(TcpClient client) {
//        Debug.writeActivity(client.getIP() + " has disconnected from the server.");
        
        // --- remove the client from the list
        clients.removeElement(client);
        
    }

    /**
     * Stops the TCP server.
    */
    public void killServer() {
    	
        try {
        	// System.out.println("TcpServer.killServer()");
            // --- stop the server
            server.close();
//            Debug.writeActivity("TCP XML/Flash server stopped");
        } catch (IOException ioe) {
//            Debug.writeActivity("Error while stopping TCP XML/Flash server");
        }
    }
}